package cn.ac.ict.fpevaluation.cluster.ap;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import cn.ac.ict.fpevaluation.fastdtw.dtw.TimeWarpInfo;
import cn.ac.ict.fpevaluation.fastdtw.test.FastDTWTest;
import cn.ac.ict.fpevaluation.fastdtw.test.MagneticSample;

import cn.ac.ict.fpevaluation.bean.AtomTrajectoryBean;
import cn.ac.ict.fpevaluation.bean.StepBean;
import cn.ac.ict.fpevaluation.fastdtw.timeseries.TimeSeriesPoint;

/**
 * 分类的步骤:
 * APBasedDirections(对方向进行聚类)
 * |
 * AP(对路径进行聚类)
 *
 * @author WUyouxiong
 *         <p>
 *         经测试之后发现, 假设聚类结果是正确的,那么室内地磁会随着时间的变化有较大的变化
 */
public class APBasedMagnetic extends AP {

    public APBasedMagnetic(List<AtomTrajectoryBean> data) {
        super(data);
    }

    /**
     * 计算两条原子轨迹间的相似度
     *
     * @param data
     * @return
     */
    @Override
    protected double[][] calSimilarity(List<AtomTrajectoryBean> data) {
        int len = data.size();
        if (len == 0) return null;
        // 把AtomTrajectoryBean变成Sample集合
        List<ArrayList<MagneticSample>> sampleLists = new ArrayList<ArrayList<MagneticSample>>();

        for (int i = 0; i < len; i++) {
            ArrayList<MagneticSample> samples = new ArrayList<MagneticSample>();

            for (StepBean step : data.get(i).getStepList()) {
                int size = step.getxMagnetic().size();
                for (int j = 0; j < size; j++) {
                    MagneticSample sample = new MagneticSample();
                    sample.setMagXOrigin(step.getxMagnetic().get(j));
                    sample.setMagYOrigin(step.getyMagnetic().get(j));
                    sample.setMagZOrigin(step.getzMagnetic().get(j));
                    samples.add(sample);
                }
            }

            sampleLists.add(samples);
        }

        double[][] result = new double[len][len];
        pa = new ArrayList<>();
        int distance = 0;
        for (int i = 0; i < len; i++) {
            for (int j = i + 1; j < len; j++) {
                //3代表是3维向量
                TimeWarpInfo t = new FastDTWTest().calDistance(gettsArray(sampleLists.get(i)), gettsArray(sampleLists.get(j)), 3);
                //距离越小相似度越大
                distance += t.getDistance();
                System.out.println("distance base Magnetic: " + distance);
                result[i][j] = -t.getDistance();
                pa.add(result[i][j]);// 存储相似度，用于计算中值
                result[j][i] = result[i][j];// 相似度是对称的
            }
        }



        // 对角线上元素赋中值
        Collections.sort(pa);
        // System.out.println("MIN" + min);
        for (int i = 0; i < trajectoryNum; i++) {
            //result[i][i] = min;
            result[i][i] = calMidValue(pa);
        }

        return result;
    }

    private static ArrayList<Object> gettsArray(ArrayList<?> samplelist) {
        ArrayList<Object> tsArray = new ArrayList<Object>();

        for (int i = 0; i < samplelist.size(); i++) {
            final ArrayList<Double> currentLineValues = new ArrayList<Double>();
            Object sample = samplelist.get(i);
            if (sample instanceof MagneticSample) {
                currentLineValues.add(Double.valueOf(((MagneticSample) sample).getMagXOrigin()));
                currentLineValues.add(Double.valueOf(((MagneticSample) sample).getMagYOrigin()));
                currentLineValues.add(Double.valueOf(((MagneticSample) sample).getMagZOrigin()));
            }

            final TimeSeriesPoint readings = new TimeSeriesPoint(currentLineValues.subList(0, currentLineValues.size()));

            tsArray.add(readings);
        }
        return tsArray;
    }

    /**
     * 启动聚类
     */
    @Override
    public List<List<AtomTrajectoryBean>> launch() {
        return super.launch();
    }


    @Override
    public String getName() {
        return getClass().getName();
    }
}